package tfts

import (
	"fmt"
	"log"
	"strconv"
	"strings"

	"github.com/spf13/viper"
)

var apScaling = "ap*"

var transfer = map[string]string{"atk": "attack", "as": "speed", "": "time", "sec": "time"}

func ReadQuickConfig(path string, roles ...Role) {
	// 初始化Viper
	v := viper.New()
	v.SetConfigName(path)   // 配置文件名称 (不含扩展名)
	v.SetConfigType("yaml") // 配置文件类型
	v.AddConfigPath(".")    // 在当前目录查找配置文件

	// 读取配置文件
	if err := v.ReadInConfig(); err != nil {
		log.Fatalf("读取配置文件失败: %v", err)
	}
	role := TestRole
	if len(roles) != 0 {
		role = roles[0]
	}

	// 获取所有英雄名称
	heroNames := v.AllSettings()
	if len(heroNames) == 0 {
		log.Fatal("配置文件中未找到英雄数据")
	}

	// 解析每个英雄
	for name := range heroNames {
		// 获取英雄配置子树
		heroViper := v.Sub(name)
		if heroViper == nil {
			log.Printf("警告: 无法获取英雄 '%s' 的配置子树", name)
			continue
		}

		// 创建配置实例
		cfg := &Config{Name: name, Role: role}

		// 解析基础属性
		if err := parseBaseAttributes(heroViper, cfg); err != nil {
			log.Printf("英雄 %s 基础属性解析失败: %v", name, err)
			continue
		}

		// 解析防御属性
		if err := parseDefence(heroViper, cfg); err != nil {
			log.Printf("英雄 %s 防御属性解析失败: %v", name, err)
			continue
		}

		// 解析技能列表
		if err := parseSkills(heroViper, cfg); err != nil {
			log.Printf("英雄 %s 技能解析失败: %v", name, err)
			continue
		}

		configs[name] = cfg
	}
}

// 解析基础属性
func parseBaseAttributes(v *viper.Viper, cfg *Config) error {
	// 获取伤害类型
	cfg.Phy = v.GetString("Phy")
	cfg.Mag = v.GetString("Mag")

	// 获取循环标志
	cfg.Loop = v.GetInt("Loop") == 1

	return nil
}

// 解析防御属性
func parseDefence(v *viper.Viper, cfg *Config) error {
	defViper := v.Sub("Stat")
	if defViper == nil {
		return nil // 防御属性是可选的
	}

	cfg.Defence = &DefenceConfig{
		Hp:         defViper.GetInt("Hp"),
		Armor:      defViper.GetInt("Ar"),
		Durability: defViper.GetInt("Dr"),
		HealAmp:    defViper.GetInt("Heal"),
		RecoverAmp: defViper.GetInt("Recover"),
		HitRecover: defViper.GetInt("Hit"),
		Omnivamp:   defViper.GetInt("Steal"),
	}

	return nil
}

// 解析技能列表
func parseSkills(v *viper.Viper, cfg *Config) error {
	skills := v.Get("Skills")
	if skills == nil {
		return nil // 技能是可选的
	}

	// 转换为切片
	skillList, ok := skills.([]interface{})
	if !ok {
		return fmt.Errorf("Skills格式错误")
	}

	for _, s := range skillList {
		skillMap, ok := s.(map[string]interface{})
		if !ok {
			return fmt.Errorf("技能格式错误")
		}

		sc := SkillConfig{}

		// 解析伤害值及施法时间
		if d1, ok := skillMap["d1"].(int); ok {
			sc.Dmg = strconv.Itoa(d1)
		} else if d1, ok := skillMap["d1"].(string); ok {
			parts := strings.Split(d1, "|")
			parts = append(parts, "0")
			sc.Dmg = parts[0]
			sc.Swing, _ = strconv.Atoi(strings.TrimSpace(parts[1]))
		}

		if d2, ok := skillMap["d2"].(int); ok {
			sc.Dmg0 = strconv.Itoa(d2)
		} else if d2, ok := skillMap["d2"].(string); ok {
			sc.Dmg0 = d2
		}

		if d3, ok := skillMap["d3"].(int); ok {
			sc.Dmg1 = strconv.Itoa(d3)
		} else if d3, ok := skillMap["d3"].(string); ok {
			sc.Dmg1 = d3
		}

		// 解析法力值 (格式: "初始值 最大值")
		if mana, ok := skillMap["mana"].(string); ok {
			parts := strings.Fields(mana)
			if len(parts) > 0 {
				// 只取最大值作为技能法力消耗
				if val, err := strconv.Atoi(parts[len(parts)-1]); err == nil {
					sc.Mana = val
				}
			}
			if len(parts) > 1 {
				if val, err := strconv.Atoi(parts[0]); err == nil {
					// 初始蓝量
					cfg.Mana = val
				}
			}
		} else if mana, ok := skillMap["mana"].(int); ok {
			sc.Mana = mana
		}

		// 解析成长表达式
		if grow, ok := skillMap["grow"]; ok {
			switch v := grow.(type) {
			case string:
				sc.Grow = v
			case int:
				sc.Grow = strconv.Itoa(v)
			}
		}

		// 解析治疗表达式
		if heal, ok := skillMap["heal"]; ok {
			switch v := heal.(type) {
			case string:
				sc.Heal = v
			case int:
				sc.Heal = apScaling + strconv.Itoa(v)
			}
		}

		// 解析护盾 (格式: "值, 持续时间")
		if shield, ok := skillMap["shield"].(string); ok {
			if sc.Buff == nil {
				sc.Buff = &BuffConfig{}
			}
			parts := strings.SplitN(shield, ",", 2)
			if len(parts) > 0 {
				sd := strings.TrimSpace(parts[0])
				if _, err := strconv.Atoi(sd); err == nil {
					sd = apScaling + sd
				}
				sc.Shield = sd
			}
			if len(parts) > 1 {
				duration := strings.Fields(parts[1])
				sc.Buff.Duration, _ = strconv.Atoi(duration[0])
				if len(duration) == 1 {
					duration = append(duration, "sec")
				}
				sc.Buff.Reduce = transfer[duration[1]]
			}
		}

		// 解析叠加效果
		if stack, ok := skillMap["stack"].(string); ok {
			sc.Stack = parseStackConfig(stack)
		} else if stack, ok := skillMap["stack"].(int); ok {
			sc.Stack = parseStackConfig(strconv.Itoa(stack))
		}

		// 解析BUFF效果
		if buff, ok := skillMap["buff"].(string); ok {
			sc.Buff = parseBuffConfig(buff)
		}

		cfg.Skills = append(cfg.Skills, sc)
	}

	return nil
}

// 解析叠加效果配置
func parseStackConfig(stack string) *StackConfig {
	parts := strings.SplitN(stack, ",", 2)
	if len(parts) == 1 {
		parts = append(parts, "1 cast")
	}

	// 解析伤害值
	value := strings.TrimSpace(parts[0])

	// 解析触发条件
	triggerParts := strings.Fields(strings.TrimSpace(parts[1]))
	if len(triggerParts) < 2 {
		triggerParts = append(triggerParts, "cast")
	}

	count, err := strconv.Atoi(triggerParts[0])
	if err != nil {
		return nil
	}

	return &StackConfig{
		Dmg:   value,
		Times: count,
		Type:  transfer[triggerParts[1]],
	}
}

// 解析BUFF配置
func parseBuffConfig(buff string) *BuffConfig {
	parts := strings.SplitN(buff, ",", 2)
	if len(parts) != 2 {
		return nil
	}

	// 解析效果标识
	effect := strings.TrimSpace(parts[0])

	// 解析持续时间
	durationParts := strings.Fields(strings.TrimSpace(parts[1]))
	if len(durationParts) < 2 {
		durationParts = append(durationParts, "")
	}

	duration, err := strconv.Atoi(durationParts[0])
	if err != nil {
		return nil
	}

	return &BuffConfig{
		Effect:   effect,
		Duration: duration,
		Reduce:   transfer[durationParts[1]],
	}
}
